using System;
using System.Collections.Specialized;
using System.IO;
using System.Windows.Forms;

namespace Liberate.CodeGenerator
{
    public static class GenerationEngine
    {
        public static StringCollection Generate(TemplateConfig config, string configFile)
        {
            AssertArgs(configFile, config);
            var files = new StringCollection();
            TemplateContextCollection contexts;
            if (config.Processor == null)
            {
                contexts = new TemplateContextCollection { new TemplateContext() };
            }
            else
            {
                contexts = config.Processor.Process();
            }
            if (contexts != null && contexts.Count > 0)
            {
                var dialog = new TargetFileSettingDialog();
                dialog.Config = config;
                dialog.ConfigFile = configFile;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    var vlTemplates = new NVelocity.Template[dialog.VMFiles.Count];
                    var templateBasePath = Path.GetDirectoryName(configFile);
                    var vlEngine = VelocityUtils.GetEngine(templateBasePath);
                    if (vlEngine != null)
                    {
                        for (var i = 0; i < dialog.VMFiles.Count; i++)
                        {
                            var vlTemplate = VelocityUtils.GetTemplate(templateBasePath, dialog.VMFiles[0].VMFilePath);
                            vlTemplates[i] = vlTemplate;
                        }
                        foreach (var context in contexts)
                        {
                            context.Merge(config.Context);
                            for (var i = 0; i < dialog.VMFiles.Count; i++)
                            {
                                var vmFile = dialog.VMFiles[i];
                                var targetFileName = VelocityUtils.Eval(vlEngine, context, vmFile.TargetFile);
                                context["FileName"] = Path.GetFileNameWithoutExtension(targetFileName);
                                var targetFile = Path.Combine(Path.GetTempPath(), targetFileName);

                                var vlTemplate = vlTemplates[i];
                                VelocityUtils.Merge(vlTemplate, context, targetFile);
                                files.Add(targetFile);
                            }
                        }
                    }
                }
            }
            return files;
        }

        private static void AssertArgs(string configFile, TemplateConfig config)
        {
            if (string.IsNullOrEmpty(configFile))
            {
                throw new ArgumentNullException("configFile");
            }
            if (config == null)
            {
                throw new ArgumentException(string.Format("config[{0}] can't be null", configFile), "config");
            }
            //if (config.Processor == null)
            //{
            //    throw new ArgumentException(string.Format("Processor[{0}] can't be null", configFile), "config");
            //}
        }
    }
}